package cn.jbolt.core.server;

import cn.jbolt.core.base.config.JBoltConfig;
import cn.jbolt.core.cache.JBoltCacheType;
import cn.jbolt.core.consts.JBoltConst;
import cn.jbolt.core.util.JBoltConsoleUtil;
import com.jfinal.core.Const;
import com.jfinal.server.undertow.UndertowConfig;
import com.jfinal.server.undertow.UndertowServer;
import io.undertow.Version;

/**
 * JBolt Undertow服务器封装
 *
 * @ClassName: JBoltServer
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年8月7日
 *
 */
public abstract class JBoltServer extends UndertowServer {
	protected JBoltServer(UndertowConfig undertowConfig) {
		super(undertowConfig);
	}
	/**
	 * 获取平台名称
	 * @return
	 */
	public abstract  String getJBoltPlatformName();

	/**
	 * 获取平台版本
	 * @return
	 */
	public abstract String getJBoltPlatformVersion();

	@Override
	public synchronized void start() {
		JBoltConfig.setLoadByServerStart();
		if (configConsumer != null) {
			configConsumer.accept(config);
			configConsumer = null; // 配置在整个生命周期只能调用一次
		}

		loadCommandLineParameter();

		try {
			JBoltConsoleUtil.printJboltcn();
			String platformName = getJBoltPlatformName();
			String platformVersion = getJBoltPlatformVersion();
			System.out.println("-----------------------------------");
			System.out.println("Starting " + platformName + " " + platformVersion + "...");
			System.out.println("-----------------------------------");
			System.out.println("System Name          : " + JBoltConfig.SYSTEM_NAME);
			System.out.println("System Version       : " + JBoltConfig.SYSTEM_VERSION);
			System.out.println("Copyright Company    : " + JBoltConfig.SYSTEM_COPYRIGHT_COMPANY);
			System.out.println("Copyright URL        : " + JBoltConfig.SYSTEM_COPYRIGHT_LINK);
			System.out.println("Deploy Environment   : " + JBoltConfig.PDEV);
			System.out.println("Saas Enable          : " + JBoltConfig.SAAS_ENABLE);
			System.out.println("Demo Mode            : " + JBoltConfig.DEMO_MODE);
			System.out.println("Dev  Mode            : " + JBoltConfig.DEV_MODE);
			System.out.println("JVM                  : " + System.getProperty("java.version"));
			System.out.println("JFinal               : " + Const.JFINAL_VERSION);
			System.out.println("JBolt Version        : " + JBoltConst.JBOLT_VERSION);
			System.out.println("Proxy Type           : " + JBoltConfig.JBOLT_PROXY_TYPE);
			System.out.println("Cache Type           : " + JBoltConfig.JBOLT_CACHE_TYPE);
			if(JBoltConfig.JBOLT_CACHE_TYPE.equals(JBoltCacheType.REDIS)){
				System.out.println("Redis Serializer     : " + JBoltConfig.JBOLT_REDIS_SERIALIZER_TYPE.name());
			}
			System.out.println("Saas Enable          : " + JBoltConfig.SAAS_ENABLE);
			System.out.println("Sentinel      Enable : " + JBoltConfig.JBOLT_SENTINEL_ENABLE);
			System.out.println("Websocket     Enable : " + JBoltConfig.JBOLT_WEBSOCKET_ENABLE);
			System.out.println("SensitiveWord Enable : " + JBoltConfig.SENSITIVE_WORD_CHECK_ENABLE);
			System.out.println("Main Datasource      : " + JBoltConfig.MAIN_DB_TYPE + "  schema:" + JBoltConfig.MAIN_DB_SCHEMA + "  name:" +JBoltConfig.MAIN_DB_NAME);
			System.out.println("Undertow Server      : " + Version.getVersionString());
			System.out.println("JFinal-Undertow      : " + version);
			String host = config.getHost();
			if("0.0.0.0".equals(host)){
				host = "localhost";
			}
			System.out.println("Http URL(Local) : http://" + host + ":" + config.getPort() + getContextPathInfo());
			if (config.isSslEnable()) {
				System.out.println("Https URL(Local): https://" + host + ":" + config.getSslConfig().getPort() + getContextPathInfo());
			}
			System.out.println("-----------------------------------");
			long start = System.currentTimeMillis();
			doStart();
			System.out.println("-----------------------------------");
			System.out.println(platformName + " " + platformVersion + " Startup Success in " + getTimeSpent(start) + " seconds(^_^)");
			System.out.println("-----------------------------------");
			printUrl();
			System.out.println("-----------------------------------");

			/**
			 * 使用 kill pid 命令或者 ctrl + c 关闭 JVM 时，调用 UndertowServer.stop() 方法， 以便触发
			 * JFinalConfig.onStop();
			 *
			 * 注意：下方代码严格测试过，只支持 kill pid 不支持 kill -9 pid
			 */
			Runtime.getRuntime().addShutdownHook(new Thread() {
				@Override
				public void run() {
					JBoltServer.this.stop();
				}
			});

		} catch (Exception e) {
			e.printStackTrace();
			stopSilently();

			// 支持在 doStart() 中抛出异常后退出 JVM，例如端口被占用，否则在 linux 控制台 JVM 并不会退出
			System.exit(1);
		}

	}

	@Override
	public synchronized void stop() {
		if (started) {
			started = false;
		} else {
			return;
		}
		System.out.println("-----------------------------------");
		System.out.println("Shutdown JBolt Server ......");
		System.out.println("-----------------------------------");
		long start = System.currentTimeMillis();
		try {
			if (hotSwapWatcher != null) {
				hotSwapWatcher.exit();
			}

			doStop();

		} catch (Exception e) {
			e.printStackTrace();
			stopSilently();
		} finally {
			System.out.println("-----------------------------------");
			System.out.println("Shutdown Complete in " + getTimeSpent(start) + " seconds. See you later (^_^)");
			System.out.println("-----------------------------------");
		}
	}

}
